

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;

import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;

import agentFramework.core.Core;
import agentFramework.core.env.Environment;

public class Window extends JFrame implements ActionListener
{
	/* core related constants */
	public static final int			TYPE_BULLY = 0;
	public static final int			TYPE_QL = 1;
	public static final int			TYPE_EPS_QL = 2;

	public static final double		QL_ALPHA = 0.4;
	public static final double 		QL_DEFAULT_PENALTY = 1.0;
	public static final double 		QL_EPSILON = 0.3;
	
	/* GUI related constants */
	public static final int 	DELAY_LOWER = 0;
	public static final int		DELAY_UPPER = 5000;
	
	public static final int 	STATE_STOP = -1;
	public static final int		STATE_STEP = 0;
	public static final int 	STATE_STEP_RUNNING = 1;
	
	public static final int		GAME_EL_FAROL = 0;
	public static final int 	GAME_DINER_DILEMMA = 1;
	
	private int state = STATE_STOP;
	private JButton 		stepButton;
	
	private JButton			loadButton;
	private JButton			statsButton;
	private JComboBox		gameChoice;
	
	
	private AbstractDrawingArea	drawingArea;
	
	private JScrollPane		statsPane;
	private JTextArea		statsTxtArea;
	private JPanel 			container;
	
	
	private JFileChooser 	fc;
	private File			file;
	private int				gameSelected;
	
	public Core				core;
	public Environment		env;
	
	public Window ()
	{
		super ("Emerge Analyzer");
		this.setLayout(null);
		this.setLocation(0, 0);
		this.setSize(Toolkit.getDefaultToolkit().getScreenSize().width - 100, 
					 Toolkit.getDefaultToolkit().getScreenSize().height - 100);
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		
		
		drawingArea = new ScenarioDrawingArea(this);
		drawingArea.setSize(800, 400);
		drawingArea.setLocation(10, 10);
		drawingArea.setBackground(Color.WHITE);
		this.add(drawingArea);
		drawingArea.repaint();
		
		gameChoice = new JComboBox(new String[]{"El Farol", "Dinner dilemma"});
		gameChoice.setSelectedIndex(0);
		gameChoice.setLocation(830, 60);
		gameChoice.setSize(160, 30);
		this.add (gameChoice);
		
		loadButton = new JButton ("Load Scenario");
		loadButton.setLocation(830, 110);
		loadButton.setSize(160, 30);
		loadButton.addActionListener(this);
		this.add (loadButton);
		
		statsButton = new JButton ("View Statistics");
		statsButton.setLocation(830, 160);
		statsButton.setSize(160, 30);
		statsButton.addActionListener(this);
		this.add (statsButton);
		
		stepButton = new JButton("Step");
		stepButton.setLocation(130, 430);
		stepButton.setSize(100, 20);
		stepButton.addActionListener(this);
		this.add(stepButton);
		
		container = new JPanel();
		container.setLocation(10, 460);
		container.setSize (800, 160);
		container.setLayout(new BorderLayout());
		
		statsTxtArea = new JTextArea();
		statsTxtArea.setEditable(false);
		statsTxtArea.setWrapStyleWord(true);
		statsPane = new JScrollPane(statsTxtArea, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
				JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
		container.add(statsPane);
		
		this.add(container);
		
		
		fc = new JFileChooser();
		file = null;
	}
	
	
	public JPanel getDrawingArea()
	{
		return this.drawingArea;
	}
	
	
	public void actionPerformed (ActionEvent e)
	{
		if (e.getSource() == loadButton)
		{
			int ret = fc.showOpenDialog(this);
			if (ret == JFileChooser.APPROVE_OPTION)
			{
				file = fc.getSelectedFile();
				
				if (gameChoice.getSelectedIndex() == GAME_EL_FAROL)
				{
					try
					{
						env = new IrishEnvironment(file.getAbsolutePath());
						core = (IrishCore) env.getCore();
						gameSelected = GAME_EL_FAROL;
					}
					catch (Exception exp) 
					{
						JOptionPane.showMessageDialog(this, "Bad format or wrong scenario!", "Error!", JOptionPane.ERROR_MESSAGE);
					}
				}
				else
				{
					try
					{
						env = new DilemmaEnvironment(file.getAbsolutePath());
						core = (DilemmaCore) env.getCore();
						gameSelected = GAME_DINER_DILEMMA;
					}
					catch (Exception exp) 
					{
						JOptionPane.showMessageDialog(this, "Bad format or wrong scenario!", "Error!", JOptionPane.ERROR_MESSAGE);
					}
				}
				
				state = STATE_STOP;
				drawingArea.repaint();
			}
		}
		
		if (e.getSource() == stepButton)
		{
			if (file == null)
			{
				JOptionPane.showMessageDialog(this, "File not loaded!", "Error!", JOptionPane.ERROR_MESSAGE);
				return;
			}
			
			if (state == STATE_STOP)
			{
			
				if (gameSelected == GAME_EL_FAROL)
				{
					IrishTester.runTest(env, (IrishCore) core, file.getAbsolutePath(), true);
				}
				else
				{
					DilemmaTester.runTest(env, (DilemmaCore) core, file.getAbsolutePath(), true); 
				}
				
				try
				{
					Thread.sleep(500);
				} catch (InterruptedException ex) {ex.printStackTrace();}
					
				state = STATE_STEP_RUNNING;
				core.getStepLock();
					
				statsTxtArea.setText("\n\nEpoch running...\n\n");
				statsTxtArea.update(statsTxtArea.getGraphics());
					
				core.getEpochLock();
				statsTxtArea.setText(statsTxtArea.getText() + "\n\nEpoch done...\n\n");
				statsTxtArea.update(statsTxtArea.getGraphics());
				core.releaseEpochLock();
				
				drawingArea.repaint();
			}
			else
			{
				if (core.getStepStatus() == Core.SIM_WAIT)
				{
					core.releaseStepLock();
					try
					{
						Thread.sleep(1000);
					} catch (InterruptedException ex) {ex.printStackTrace();}
					
					core.getStepLock();
					
					statsTxtArea.setText("\n\nEpoch running...\n\n");
					statsTxtArea.update(statsTxtArea.getGraphics());
					
					core.getEpochLock();
					statsTxtArea.setText(statsTxtArea.getText() + "\n\nEpoch done...\n\n");
					statsTxtArea.update(statsTxtArea.getGraphics());
					core.releaseEpochLock();
					
					drawingArea.repaint();
					
				}
				else
				{
					if (core.isAlive())
					{
						JOptionPane.showMessageDialog(this, "Epoch running!", "Error!", JOptionPane.ERROR_MESSAGE);
					}
					else
					{
						JOptionPane.showMessageDialog(this, "Simulation ended!", "Error!", JOptionPane.ERROR_MESSAGE);
					}
				}
				
			}
			
		}
		
		if (e.getSource() == statsButton)
		{
			if (file == null)
			{
				JOptionPane.showMessageDialog(this, "File not loaded!", "Error!", JOptionPane.ERROR_MESSAGE);
				return;
			}
			
			if (state == STATE_STOP)
			{
				JOptionPane.showMessageDialog(this, "Simulation not started!", "Error!", JOptionPane.ERROR_MESSAGE);
				return;
			}
			/* TODO: print stats */
			if (core.getStepStatus() == Core.SIM_WAIT)
			{
				String s = "";
				if (gameSelected == GAME_EL_FAROL)
				{
					s = statsTxtArea.getText() + "\n\n" + IrishTester.printStatistics((IrishCore)core);
				}
				else
				{
					s = statsTxtArea.getText() + "\n\n" + DilemmaTester.printStatistics((DilemmaCore)core);
				}
				
				statsTxtArea.setText(s);
				statsTxtArea.update(statsTxtArea.getGraphics());
			}
			else
			{
				JOptionPane.showMessageDialog(this, "Epoch running!", "Error!", JOptionPane.ERROR_MESSAGE);
			}
		}
		
	}
	
}
